<?php

use think\Collection;
use think\facade\Config;
use think\facade\Cache;
use think\facade\Response;
use curl\Curlrequest;
use think\facade\Env;
use think\facade\Log;
use think\Model;
use think\facade\App;
use qrcode\QrcodeUpload;
use alioss\OssAli;
    
    /**
 * 封装返回值
 * @param $result
 * @param $errorCode
 * @param string $errorMessage
 * @return array
 */
function send_response($result, $errorCode, $errorMessage = '') {
    $response = [];
    $response['errorCode'] = $errorCode;
    $response['message'] = $errorMessage ? $errorMessage : Config::pull('errorcode')[$errorCode];
    if (is_array($result)) {
        $response['data'] = $result;
    }
    
    if ($result instanceof Collection || $result instanceof Model) {
        $response['data'] = $result->toArray();
    }

    return $response;
}

/**
 * ip信息淘宝付费接口
 * @param $ip
 * @return mixed
 */
function get_ip_data($ip) {
    $appCode = "0640cdab85e449f1b7881a5bf9d8cc5c";
    $headers = array();
    array_push($headers, "Authorization:APPCODE " . $appCode);
    $request = Curlrequest::get("https://api01.aliyun.venuscn.com/ip?ip=" . $ip, $headers, 10);
    $info = json_decode($request, true);
    if(isset($info['ret']) && $info['ret'] == 200) {
        $info['data']['province'] = $info['data']['region'];
        return $info['data'];
    } else {
        if(check_intranet($ip)) {
            $info['data']['province']   = '内网';
            $info['data']['country_id'] = 'CN';
            $info['data']['country']    = '内网';
            $info['data']['city']       = '内网';
            $info['data']['ip']         = $ip;
            $info['data']['isp']        = '内网';
            $info['data']['region']     = '内网';
        } else {
            $info['data']['province']   = '未知IP';
            $info['data']['country_id'] = 'CN';
            $info['data']['country']    = '未知IP';
            $info['data']['city']       = '未知IP';
            $info['data']['ip']         = $ip;
            $info['data']['isp']        = '未知IP';
            $info['data']['region']     = '未知IP';
        }
        return $info['data'];
    }
}

/**
 * 检查是否为内网ip
 * @param $ip
 * @return int
 */
function check_intranet($ip) {
    $addrArr = array(
        '10.0.0.0|10.255.255.255',
        '172.16.0.0|172.31.255.255',
        '192.168.0.0|192.168.255.255',
        '169.254.0.0|169.254.255.255',
        '127.0.0.0|127.255.255.255'
    );
    $longIp = ip2long($ip);
    if($longIp != -1) {
        foreach($addrArr AS $addr) {
            list($start, $end) = explode('|', $addr);
            if($longIp >= ip2long($start) && $longIp <= ip2long($end))
                return true;
        }
    }
    return false;
}

/**
 * 生成指定长度的随机字符串
 * @param int $len 长度
 * @param string $type
 * @return string
 */
function random_string($len = 8, $type = 'str') {
    switch ($type) {
        case 'str': {
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            break;
        }
        case 'int': {
            $chars = '0123456789';
            break;
        }
        default: {
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
            break;
        }
    }
    $chars = str_shuffle($chars);
    return substr($chars, 0, $len);
}

/**
 * 重新指定数组的索引
 * @param array $arr 数组
 * @param string $key 键名
 * @return array
 */
function reindex_array($arr, $key) {
    if(!is_array($arr) || empty($arr)) {
        return array();
    }

    $row = array_shift($arr);
    if(!array_key_exists($key, $row)) {
        return array();
    }
    array_unshift($arr, $row);

    $res = array();
    foreach($arr as $row) {
        $res[$row[$key]] = $row;
    }

    return $res;
}


/**
 * 提取数组某一个key的值
 * @param array $arr
 * @param string $extract_key
 * @return array
 */
function extract_array($arr, $extract_key) {
    $res = array();
    if(is_array($arr)) {
        foreach($arr as $row) {
            $res[] = $row[$extract_key];
        }
    }

    return $res;
}

function get_cross_headers() {
    $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*";
    $headers   = [
        "Access-Control-Allow-Origin"      => $host_name,
        "Access-Control-Allow-Credentials" => 'true',
        "Access-Control-Allow-Headers"     => "x-token,x-uid,x-token-check,x-requested-with,content-type,Host,Auth-Token,Authorization",
        "Access-Control-Expose-Headers"    => 'Auth-Token'
    ];

    return $headers;
}

/**
 * @desc 生成订单号
 * @return string
 */
function generate_order_number() {
    $order = date('Y') . date('m') . date('d') . substr(time(), -5);
    $order .= substr(microtime(), 2, 5) . sprintf('%03d', mt_rand(0, 999));

    return $order;
}

/**
 * @desc 生成订单号
 * @return string
 */
function generate_order_no() {
    $uniqueID = substr(uniqid(), 7, 13);
    $order = date('Ymd').substr(implode(NULL, array_map('ord', str_split($uniqueID, 1))), 0, 12);
    return $order;
}

//密码生成方法
function encrypt_password($password, $salt) {
    $password = trim($password);

    return md5($password . $salt);
}


function array_ksort($list) {
    ksort($list);
    foreach($list as $k => $v) {
        if(is_array($v)) {
            $list[$k] = array_ksort($v);
        }
    }

    return $list;
}

/**
 * 计算两个日期之间相差的天数
 */
function count_days($a, $b) {
    return round(abs(strtotime($a) - strtotime($b)) / 86400);
}

/**
 * 二维数组按照某字段排序
 * $array 待排序数组
 * $key 排序的键名
 * $sort 1 - 默认，按升序排列。2 - 按降序排列。(Z-A)
 * return 排序后的数组
 */
function array_sort_bykey($array = [], $key = '', $sort = 1) {
    $keyArray = array();
    foreach($array as $v) {
        $keyArray[] = $v[$key];
    }

    $sort = ($sort == 1) ? SORT_ASC : SORT_DESC;
    array_multisort($keyArray, $sort, $array);

    return $array;
}

/**
 * 系统加密方法
 * @param string $data 要加密的字符串
 * @param string $key 加密密钥
 * @param int $expire 过期时间 单位 秒
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_encrypt($data, $key = '', $expire = 0) {
    $key  = md5($key);
    $data = base64_encode($data);
    $x    = 0;
    $len  = strlen($data);
    $l    = strlen($key);
    $char = '';

    for($i = 0; $i < $len; $i++) {
        if($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time() : 0);

    for($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }

    return str_replace(array(
        '+',
        '/',
        '='
    ), array(
        '-',
        '_',
        ''
    ), base64_encode($str));
}

/**
 * 获取冷数据表-年月信息
 * @param $startDate
 * @param $endDate
 * @return array
 */
function get_cold_data_ym($startDate, $endDate) {

    $sTime = strtotime($startDate);
    $eTime = strtotime($endDate);

    $m = date("m", $sTime);
    $y = date("Y", $sTime);

    $sym = date("Ym", $sTime);
    $eym = date("Ym", $eTime);

    $ym = [];
    $i  = 0;

    $_startDate = $startDate;
    $_endDate   = date("Y-m-01 0:00:00", mktime(0, 0, 0, $m + 1, 1, $y));

    while($sym <= $eym) {

        $tmp          = [];
        $tmp['ym']    = $sym;
        $tmp['sdate'] = $_startDate;
        $tmp['edate'] = $_endDate;
        $ym[]         = $tmp;

        $i++;
        $m1time = mktime(0, 0, 0, $m + $i, 1, $y);

        $sym        = date("Ym", $m1time);
        $_startDate = date("Y-m-01 0:00:00", $m1time);
        $_endDate   = ($sym == $eym) ? $endDate : date("Y-m-01 0:00:00", mktime(0, 0, 0, $m + $i + 1, 1, $y));
    }

    return $ym;
}


/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取（有可能被伪装）
 * @return mixed
 */
function get_client_ip($type = 0, $adv = true) {
    $type = $type ? 1 : 0;
    static $ip = null;
    if($ip !== null) return $ip[$type];
    if($adv) {
        if(isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip = trim($arr[0]);
        } elseif(isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif(isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip   = $long ? array(
        $ip,
        $long
    ) : array(
        '0.0.0.0',
        0
    );

    return $ip[$type];
}


/**
 * 批量更新
 * @param string $tableName 表名（含前缀）
 * @param array $data 数据
 * @param string $field 主键字段
 * @return bool|int
 */
function batch_update($tableName = '', $data = array(), $field = '') {
    if(!$tableName || !$data || !$field) {
        return false;
    } else {
        $sql = 'UPDATE ' . $tableName;
    }
    $con    = [];
    $conSql = [];
    $fields = [];
    foreach($data as $key => $value) {
        $x = 0;
        foreach($value as $k => $v) {
            if($k != $field && !isset($con[$x]) && $x == 0) {
                $con[$x] = " set {$k} = (CASE {$field} ";
            } elseif($k != $field && !isset($con[$x]) && $x > 0) {
                $con[$x] = " {$k} = (CASE {$field} ";
            }
            if($k != $field) {
                $temp = $value[$field];

                if(is_operator($v) || is_numeric($v)) {
                    $conSql[$x] = !isset($conSql[$x]) ? " WHEN '{$temp}' THEN {$v} " : $conSql[$x] . " WHEN '{$temp}' THEN {$v} ";
                } else {
                    $conSql[$x] = !isset($conSql[$x]) ? " WHEN '{$temp}' THEN '{$v}' " : $conSql[$x] . " WHEN '{$temp}' THEN '{$v}' ";
                }

                $x++;
            }
        }
        $temp = $value[$field];
        if(!in_array($temp, $fields)) {
            $fields[] = $temp;
        }
    }
    $num = count($con) - 1;
    foreach($con as $key => $value) {
        foreach($conSql as $k => $v) {
            if($k == $key && $key < $num) {
                $sql .= $value . $v . ' end),';
            } elseif($k == $key && $key == $num) {
                $sql .= $value . $v . ' end)';
            }
        }
    }
    $str = implode(',', $fields);
    $sql .= " where {$field} in({$str})";

    $query  = new \think\db\Query();
    $result = $query->execute($sql);

    return $result;
}

function is_operator($str) {

    $operator_array = array(
        "+",
        "-",
        "*",
        "/",
        "%"
    );

    foreach($operator_array as $operator) {
        if(strpos($str, $operator) !== false) {
            return true;
        }
    }

    return false;
}


/**
 * 多条件批量更新
 * @param string $tableName 表名（含前缀）
 * @param array $data 数据
 * @param string $whereField 条件字段
 * @param string $whereIndexField 主键索引字段
 * @return bool|int
 */
function batch_update_multi_key($tableName = '', $data = [], $whereField = '', $whereIndexField = '') {
    if(!$tableName || !$data || !$whereField) {
        return false;
    } else {
        $sql = 'UPDATE ' . $tableName . ' set ';
    }

    $whenFields = [];
    if(is_array($whereField)) {
        $whenFields = $whereField;
    } elseif(is_string($whereField) && strpos($whereField, ",")) {
        $whenFields = explode(",", $whereField);
    } elseif(is_string($whereField)) {
        $whenFields = [$whereField];
    }

    $con     = [];
    $conSql  = [];
    $default = [];
    $where   = [];

    foreach($data as $key => $row) {
        $x        = 0;
        $when_exp = "";

        foreach($row as $field => $value) {
            if(in_array($field, $whenFields)) {
                $when_exp = $when_exp ? $when_exp . " and {$field}={$value}" : "{$field}={$value}";
            }
        }

        foreach($row as $k => $v) {
            if(!in_array($k, $whenFields) && !$con[$x]) {
                $con[$x] = " {$k} = (CASE ";
            }
            if(!in_array($k, $whenFields) && !$default[$x]) {
                $default[$x] = " ElSE {$k} ";
            }
            if(!in_array($k, $whenFields)) {
                $conSql[$x] .= " WHEN {$when_exp} THEN '{$v}' ";
                $x++;
            }
        }

        $tmp = $row[$whereIndexField];
        if($whereIndexField && !in_array($tmp, $where)) {
            $where[] = $tmp;
        }
    }

    $num = count($con) - 1;
    foreach($con as $key => $value) {
        foreach($conSql as $k => $v) {
            if($k == $key && $key < $num) {
                $sql .= $value . $v . $default[$key] . ' end),';
            } elseif($k == $key && $key == $num) {
                $sql .= $value . $v . $default[$key] . ' end)';
            }
        }
    }

    if(!empty($where)) {
        $whereStr = implode(',', $where);
        $sql      .= " where {$whereIndexField} in({$whereStr})";
    }

    $query  = new \think\db\Query();
    $result = $query->execute($sql);

    return $result;
}

/**
 * 生成签名结果
 * @param array $params 已排序要签名的数组
 * @param string $signKey 加密key
 * @return string 签名结果字符串
 */
function build_request_sign($params, $signKey) {
    $linkString = build_link_string($params);

    return md5($linkString . $signKey);
}

/**
 * 创建充值中心签名
 * @param $params
 * @param $signKey
 * @return string
 */
function build_request_pay_center_sign($params, $signKey) {
    ksort($params);
    $sb_list = array();
    foreach($params as $key => $value) {
        if($key == "sign" || $value == "") {
            continue;
        }
        if(is_array($value) && sizeof($value) == 0) {
            continue;
        }
        $sb_list[] = $key . '=' . $value;
    }
    $str = implode('&', $sb_list);
    //如果存在转义字符，那么去掉转义
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }

    return md5($str . $signKey);
}

/**
 * modifyDate：2018年11月30日16:47:25
 * 生成待签名字符串
 * 对数组里的每一个值从a到z的顺序排序，若遇到相同首字母，则看第二个字母以此类推。
 * 排序完成后，再把所有数组值以‘&’字符连接起来
 * @param  array $params 待签名参数
 * @return string
 */
function build_link_string($params) {
    unset($params['sign']);
    ksort($params);
    reset($params);

    $param = [];
    foreach($params as $k => $v){
        if($v == '' || $v === null){
            continue;
        }
        array_push($param , $k . '=' . $v);
    }
    $queryString = implode('&',$param);
    if(get_magic_quotes_gpc()) {
        $queryString = stripslashes($queryString);
    }
    return $queryString;
}


//报表下载返回格式
//list下载的数据，title列标题
//list为空时提示不能下载
function export_title_format($list = [], $title = []) {
    if(empty($list) || !is_array($list)) {
        return $title;
    }

    $titleKey = array_keys($list[0]);

    return array_combine($titleKey, $title);
}

function call_pay_center_api($apiUrl, $requestData = false) {
    $appConfig       = Config::get('pay.app_config');
    $signKey         = \think\facade\App::model('common/SystemConfig')->getConfig('PAY_CENTER_SIGN_KEY');
    $params['appId'] = $appConfig['app_id'];
    $params['nonce'] = random_string(32);
    if(is_array($requestData)) {
        $params = array_merge($params, $requestData);
    }
    $sign           = build_request_sign($params, $signKey);
    $params['sign'] = $sign;
    $result         = Curlrequest::post($apiUrl, $params);
    //Log::write($apiUrl."请求的参数:". print_r($params, true)."返回的数据:". print_r($result, true));
    if(empty($result)) {
        return false;
    }

    return json_decode($result, true);
}

/**
 * 递归数组，去掉默认的字符和驼峰转换；eg: ul_user_id => userId
 * @param $data array 需要格式化的数据
 * @param $replaceString string 需要去掉的字符
 * @return mixed
 */
function output_format($data, $replaceString = '')
{
    if ($data instanceof Collection || $data instanceof Model) {
        $data = $data->toArray();
    }
    if (!is_array($data) || empty($data)) {
        return [];
    }
    $formatData = [];
    foreach ($data as $key => $val) {
        //替换字符
        if ($replaceString) {
            $newKey = str_replace($replaceString . '_', '', $key);
        } else {
            $newKey = $key;
        }
        
        //转换驼峰
        $newKey = lcfirst(str_replace(' ', '', ucwords(str_replace(['_'], ' ', $newKey))));
        
        //递归val
        if (is_array($val)) {
            $formatData[$newKey] = output_format($val, $replaceString);
        } else {
            //接口不返回null
            if ($val === null) {
                $val = '';
            }
            $formatData[$newKey] = $val;
        }
    }
    return $formatData;
}

/**
 * 数组去除空值
 * @param $arr array 数组
 * @param $trim bool 是否删除两边空格
 * @return string|array
 */
function array_remove_empty($arr, $trim = true) {
    if (!is_array($arr)) return false;
    foreach($arr as $key => $value){
        if (is_array($value)) {
            array_remove_empty($arr[$key]);
        } else {
            $value = ($trim == true) ? trim($value) : $value;
            if ($value === "") {
                unset($arr[$key]);
            } else {
                $arr[$key] = $value;
            }
        }
    }
    return $arr;
}

/**
 * 截取3位小数保留精度一致,不会进位
 * @param float $float
 * @param int $num
 * @return float
 */
function cut_floor($float , $num = 3){
    switch($num){
        case 2:{
            $float = floor($float * 100)*1.00/100.00;
            break;
        }
        case 3:{
            $float = floor($float * 1000)*1.000/1000.000;
            break;
        }
        case 4:{
            $float = floor($float * 10000)*1.0000/10000.0000;
            break;
        }
        default : {
            $float = floor($float * 100)*1.00/100.00;
        }
    }
    return $float;
}

/**
 * 判断数组是否二维数组
 * @param $data
 * @return bool
 */
function is_multi_array($data){
    if(count($data) == count($data,COUNT_RECURSIVE)){
        return false;
    }else{
        return true;
    }
}

/**
 * 计算当前时间所在周期, 默认统计周期5分钟
 * @param int $cycle
 * @return mixed
 */
function getTimeRange($cycle = 5) {
    $hour   = date('H');
    $minute = date('i');
    $end = floor(($hour * 60 + $minute) / $cycle);
    if($end == 0) {
        $arr['startTime'] = '00:00:00';
        $arr['endTime']   = '00:05:00';
    } else {
        $arr['startTime'] = floor(($end - 1) * $cycle / 60) . ':' . ($end - 1) * $cycle % 60 . ':00';
        $arr['endTime'] = floor($end * $cycle / 60) . ':' . $end * $cycle % 60 . ':00';
    }
    return $arr;
}

/**
 * 计算据现在间隔时间
 * @param int $time
 * @return bool|string
 */
function time2zh($time){
    $now_time = time();
    $zh = date('Y-m-d H:i:s', $time);
    $diff = $now_time - $time;
    if($diff < 60){
        $zh = $diff.'秒';
    }elseif($diff < 3600){
        $zh = floor($diff/60).'分';
    }elseif($diff < 3600 * 24) {
        $zh = floor($diff/3600).'小时';
    }elseif($diff < 3600 * 24 * 7){
        $zh = floor($diff/86400).'天';
    }
    return $zh;
}

/**
 * 封装返回值
 * @param string $data
 * @throws HttpResponseException
 */
function response_exception($data = '') {
    $type = Config::get('app.default_ajax_return');
    $response = Response::create($data, $type);
    throw new think\exception\HttpResponseException($response);
}

/**
 * 获取指定日期段内每一天的日期
 * @param  Date  $startDate 开始日期
 * @param  Date  $endDate   结束日期
 * @return Array
 */
function getDateFromRange($startDate, $endDate){

    $starTimestamp = strtotime($startDate);
    $endTimestamp = strtotime($endDate);

    // 计算日期段内有多少天
    $days = ($endTimestamp-$starTimestamp)/86400+1;

    // 保存每天日期
    $date = array();
    for($i=0; $i<$days; $i++){
        $date[] = date('Y-m-d', $starTimestamp+(86400*$i));
    }
    return $date;
}

/**
 * 验证时间格式
 * @param $dateTime
 * @return bool|false|string
 */
function validateTime(&$dateTime) {
    if(!$dateTime) {
        $dateTime = date('Y-m-d H:00:00');
    } else {
        if(!strtotime($dateTime)) {
            return false;
        }
        $dateTime = date('Y-m-d H:00:00', strtotime($dateTime));
    }
    return true;
}

/**
 * 查询时间范围跨度默认小于等于30天
 * @param $startDate
 * @param $endDate
 * @return bool
 */
function limitTimeRange($startDate, $endDate) {
    $starTimestamp = strtotime($startDate);
    $endTimestamp = strtotime($endDate);

    //计算日期段内有多少天
    $days = ($endTimestamp-$starTimestamp)/86400+1;

    //判断时间跨度是否超过指定，默认30天
    if($days > 30) {
        return false;
    }
    return true;
}

/**
 * @desc 使用header下载文件
 * @param string file_path  文件路径
 * @return null
 */
function downloadFile($file_path){
    //判断路径是否存在
    if(!file_exists($file_path)){
        echo "文件不存在";
        return;
    }
    
    $fp = fopen ($file_path, "rb"); 	// 文件以二进制形式打开
    $ua = $_SERVER["HTTP_USER_AGENT"];
    
    //取得文件信息
    $file_size = filesize($file_path);
    $file_name = basename($file_path);
    $encoded_file_name = urlencode($file_name);
    $encoded_file_name = str_replace("+", "%20", $encoded_file_name);
    
    header('Content-Type: application/octet-stream;charset=utf-8');
    header("Accept-Ranges:bytes");
    header("Accept-Length:".$file_size);
    
    // 兼容多浏览器下载
    if (preg_match("/MSIE/", $ua)) {
        header('Content-Disposition: attachment; filename=' . $encoded_file_name);
    } else if (preg_match("/Firefox/", $ua)) {
        header('Content-Disposition: attachment; filename*=utf8\'\'' . $file_name);
    } else {
        header('Content-Disposition: attachment; filename=' . $file_name);
    }
    
    // 清除缓存很重要
    ob_clean();
    flush();
    // 清除缓存很重要
    
    $buffer = 1024;
    $buffer_count = 0;
    
    while (!feof($fp) && $file_size - $buffer_count > 0) {
        $data = fread($fp, $buffer);
        $buffer_count += $buffer;
        echo $data;
    }
    
    fclose($fp);
    
    exit(); // 一定要使用exit退出，否则会导致输出excel文件无法打开
}

/**
 * @desc 文件大小转换  eg：118050056 = 112.58MB
 * @param $byte
 * @return string
 */
function calculate_file_size($byte) {
    $KB = 1024;
    $MB = 1024 * $KB;
    $GB = 1024 * $MB;
    $TB = 1024 * $GB;
    
    if ($byte < $KB) {
        return $byte . "B";
        
    } elseif ($byte < $MB) {
        return round($byte / $KB, 2) . "KB";
        
    } elseif ($byte < $GB) {
        return round($byte / $MB, 2) . "MB";
        
    } elseif ($byte < $TB) {
        return round($byte / $GB, 2) . "GB";
        
    } else {
        return round($byte / $TB, 2) . "TB";
    }
}

/**
 * @desc 文件删除
 * @param $path
 */
function delete_dir($path){
    //如果是目录则继续
    if(is_dir($path)){
        //扫描一个文件夹内的所有文件夹和文件并返回数组
        $p = scandir($path);
        foreach($p as $val){
            //排除目录中的.和..
            if($val !="." && $val !=".."){
                //如果是目录则递归子目录，继续操作
                if(is_dir($path.$val)){
                    //子目录中操作删除文件夹和文件
                    delete_dir($path.$val.'/');
                    //目录清空后删除空文件夹
                    @rmdir($path.$val.'/');
                }else{
                    //如果是文件直接删除
                    unlink($path.$val);
                }
            }
        }
    }
}

/**
 * @desc url base64编码
 * @param $string
 * @return mixed|string
 */
function url_safe_b64encode($string) {
    $data = base64_encode($string);
    $data = str_replace(array('+','/','='),array('-','_',''),$data);
    return $data;
}

/**
 * @desc url base64编码
 * @param $string
 * @return mixed|string
 */
function url_safe_b64decode($string) {
    $data = str_replace(array('-','_'),array('+','/'),$string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

/**
 * @desc 字符转hex编码
 * @param $string
 * @return mixed|string
 */
function string2hex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++){
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

/**
 * @desc hex编码转字符
 * @param $hex
 * @return mixed|string
 */
function hex2string($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}

/**
 * @desc 创建短信验证码
 * @param string $key 缓存key
 * @param int $length 短信码长度
 * @param int $expire 默认缓存时间
 * @return string
 */
function create_msg_code($key, $length = 6, $expire = 300){
    $chars = '0123456789';
    $chars = str_shuffle($chars);
    $code  = substr($chars, 0, $length);

    //生产环境发送正式验证码
    if(Env::get('app.environment') == 'production'){
        Cache::set('create_msg_code_'.$key, $code, $expire);
    } else {
        $code = '123456';
        Cache::set('create_msg_code_'.$key, $code, $expire);
    }
    //Log::write('验证码：'.$code,'info', true);
    return $code;
}

/**
 * @desc 验证短信验证码
 * @param string $key 缓存key
 * @param string $code 默认缓存时间
 * @return string
 */
function check_msg_code($key, $code) {
    $cacheCode = Cache::get('create_msg_code_'. $key);
    //Log::write('CacheCode：'.$cacheCode,'info', true);
    if(strcmp($code, $cacheCode) != 0){
        return false;
    }else{
        return true;
    }
}

/**
 * @desc 验证签名
 * @param $data
 * @param $signKey
 * 生成待签名字符串
 * 对数组里的每一个值从a到z的顺序排序，若遇到相同首字母，则看第二个字母以此类推。
 * 排序完成后，再把所有数组值以‘&’字符连接起来
 * @return bool
 */
function checkSign($data, $signKey) {
    $client_sign = $data['sign'];
    unset($data['sign']);
    ksort($data);
    
    $param = [];
    foreach($data as $k=>$v) {
        if($v == '' || $v === null) {
            continue;
        }
        array_push($param , $k . '=' . $v);
    }
    $queryString = implode('&',$param);
    
    if(get_magic_quotes_gpc()) {
        $queryString = stripslashes($queryString);
    }
    //Log::write('post参数为：', 'info', true);
    //Log::write($queryString, 'info', true);

    //Log::write('secretKey参数为：', 'info', true);
    //Log::write($signKey, 'info', true);

    $sign = md5($queryString . $signKey);

    //Log::write('正确的签名为：', 'info', true);
    //Log::write($sign, 'info', true);

    return $client_sign == strtolower($sign);
}

/**
 * @desc 获取带参数的url
 * @param string $url
 * @param array $data
 * @return string
 */
function getParamsUrl($url, $data) {
    if(is_array($data)) {
        $param = [];
        foreach($data as $k=>$v) {
            if($v == '' || $v === null) {
                continue;
            }
            array_push($param , $k . '=' . $v);
        }
        $queryString = implode('&',$param);
    }else {
        $queryString = $data;
    }
    /**
     * 解析原始地址
     * 完整链接：http://aa.abc.com/download/v3?agentCode=55421603&channelCode=android
     * array() {
     *    "scheme"=> "http"
     *    "host"  => "aa.abc.com"
     *    "path"  => "/download/v3"
     *    "query" => "agentCode=55421603&channelCode=android"
     * }
     */
    $parseInfo = parse_url($url);
    if(isset($parseInfo['query'])) {
        return $url.'&'.$queryString;
    }else {
        return $url.'?'.$queryString;
    }
}
